<script lang="ts" setup>
import type { flowable } from '@/index.d';
import {
  urls,
  dateTimeToDateTime,
  useTabsViewStore,
  api,
  getCommentListByProcessInstanceId,
  getTaskInstanceVOListByCondition,
  getLoginUserInfo,
  getProcessInstanceVOByCondition
} from '@/index';
import router from '@/router';
import qs from 'qs';
import { useRequest } from 'vue-request';

//用户账号和用户姓名
const { loginUserUsername, loginUserName } = getLoginUserInfo();

const props = defineProps({
  processInstanceId: String
});

const emit = defineEmits<{
  (e: 'handleStartProcessInstance'): void;
}>();

//当点击关闭按钮时，删除当前tab，导航到流程实例列表视图
const handleClose = async () => {
  const currentRoute = router.currentRoute;
  const { removeByPath } = useTabsViewStore();
  await removeByPath(currentRoute.value.fullPath);
  router.push('/flowable/processInstance');
};

// 审批内容中的相关表单是否可编辑
const isFormDataEditable = ref<boolean>(false);

const showHandleStartProcessInstanceButtonLoading = ref(false);

const handleStartProcessInstance = () => {
  showHandleStartProcessInstanceButtonLoading.value = true;
  emit('handleStartProcessInstance');
  showHandleStartProcessInstanceButtonLoading.value = false;
  isFormDataEditable.value = false;
};

//获取当前流程的实例详情
const getProcessInstanceVOByConditionPromise = () => {
  return getProcessInstanceVOByCondition('processInstanceId', props.processInstanceId as string);
};

const { data: getProcessInstanceVOData, runAsync: getProcessInstanceVORun } = useRequest(
  getProcessInstanceVOByConditionPromise,
  {
    manual: true
  }
);

const processInstanceId = computed(() => {
  if (getProcessInstanceVOData.value) {
    return getProcessInstanceVOData.value.processInstanceId;
  } else {
    return undefined;
  }
});

//根据流程实例id获取评论列表
const getCommentListByProcessInstanceIdPromise = () => {
  return getCommentListByProcessInstanceId(props.processInstanceId as string);
};

const {
  data: getCommentListByProcessInstanceIdData,
  loading: getCommentListByProcessInstanceIdLoading,
  run: getCommentListByProcessInstanceIdRun
} = useRequest(getCommentListByProcessInstanceIdPromise, {
  manual: true
});

//获取当前实例的运行任务列表
const getTaskVOListPromise = () => {
  return getTaskInstanceVOListByCondition('processInstanceId', props.processInstanceId as string);
};

const {
  data: getTaskVOListData,
  loading: getTaskVOListLoading,
  run: getTaskVOListRun
} = useRequest(getTaskVOListPromise, {
  manual: true
});

//标记是否只展示我的任务
const showMyTaskOnly = ref<boolean>(true);

const taskList = computed(() => {
  if (showMyTaskOnly.value) {
    return getTaskVOListData.value?.filter(item => item.taskAssignee === loginUserUsername);
  } else {
    return getTaskVOListData.value;
  }
});

//我的第一个运行任务
const myFirstTaskVO = computed(() => {
  if (getTaskVOListData.value?.length) {
    const myTask = getTaskVOListData.value?.filter(item => item.taskAssignee === loginUserUsername);
    if (myTask.length) {
      return myTask[0];
    } else {
      return null;
    }
  } else {
    return null;
  }
});

const reloadPageTable = () => {
  delete taskOperate.commentMessage;
  getProcessInstanceVORun();
  getCommentListByProcessInstanceIdRun();
  getTaskVOListRun();
};

const taskOperate = reactive<flowable.TaskOperateType>({
  processInstanceId: props.processInstanceId as string,
  userNameFrom: loginUserName,
  userUsernameFrom: loginUserUsername
});

const checkHandleTaskInput = (): boolean => {
  if (taskOperate.commentType === undefined) {
    ElMessage.error('请选择操作类型');
    return false;
  }
  return true;
};

const handleTask = async () => {
  if (!checkHandleTaskInput()) {
    return;
  }
  taskOperate.taskId = myFirstTaskVO.value?.taskId || getTaskVOListData.value?.at(0)?.taskId;
  try {
    const res = await api({
      method: 'post',
      url: urls.taskInstance + '/doTask',
      data: qs.stringify(taskOperate)
    });
    if (res.status === 200) {
      if (res.data.status) {
        reloadPageTable();
        ElMessage.success(taskOperate.commentType + '成功');
      } else {
        ElMessage.error(res.data.msg);
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error: any) {
    ElMessage.error(error);
  }
};

const showCanChangeFormDataEditable = computed(() => {
  if (
    props.processInstanceId === undefined ||
    getProcessInstanceVOData.value?.processInstanceIsSuspended
  ) {
    return false;
  } else {
    if (myFirstTaskVO.value?.taskName === '起草节点') {
      return true;
    } else {
      return false;
    }
  }
});

const showHandleStartProcessInstanceButton = computed(() => {
  if (props.processInstanceId === undefined) {
    return true;
  } else if (!isFormDataEditable.value) {
    return false;
  } else {
    if (getProcessInstanceVOData.value?.processInstanceIsSuspended) {
      return false;
    } else if (myFirstTaskVO.value?.taskName === '起草节点') {
      return true;
    } else {
      return false;
    }
  }
});

const showCompleteTaskOption = computed(() => {
  return (
    myFirstTaskVO.value?.taskDelegationState !== 'PENDING' &&
    !myFirstTaskVO.value?.processInstanceIsSuspended
  );
});

const showRejectTaskOption = computed(() => {
  return (
    myFirstTaskVO.value?.taskDelegationState !== 'PENDING' &&
    myFirstTaskVO.value?.taskName !== '起草节点'
  );
});

const showChangeAssigneeTaskOption = computed(() => {
  return (
    myFirstTaskVO.value?.taskDelegationState !== 'PENDING' &&
    myFirstTaskVO.value?.taskName !== '起草节点'
  );
});

const showDelegateTaskOption = computed(() => {
  return (
    myFirstTaskVO.value?.taskDelegationState !== 'PENDING' &&
    myFirstTaskVO.value?.taskName !== '起草节点'
  );
});

const showResolveTaskOption = computed(() => {
  return myFirstTaskVO.value?.taskDelegationState === 'PENDING';
});

//显示废弃（删除）按钮
const showDeleteProcessInstanceButton = computed(() => {
  //流程启动人在流程没有结束时可以删除流程
  return (
    getProcessInstanceVOData.value?.processInstanceStartUserId === loginUserUsername &&
    !getProcessInstanceVOData.value.processInstanceEndTime
  );
});
//显示暂停按钮
const showSuspendProcessInstanceButton = computed(() => {
  //流程启动人在流程没有结束时可以删除流程
  return (
    !getProcessInstanceVOData.value?.processInstanceEndTime &&
    getProcessInstanceVOData.value?.processInstanceIsSuspended === false &&
    getProcessInstanceVOData.value?.processInstanceStartUserId === loginUserUsername
  );
});

const showActiveProcessInstanceButton = computed(() => {
  return (
    !getProcessInstanceVOData.value?.processInstanceEndTime &&
    getProcessInstanceVOData.value?.processInstanceIsSuspended &&
    getProcessInstanceVOData.value?.processInstanceStartUserId === loginUserUsername
  );
});

const showWithDrawProcessInstanceButton = computed(() => {
  return (
    getProcessInstanceVOData.value?.processInstanceIsSuspended === false &&
    getProcessInstanceVOData.value?.processInstanceStartUserId === loginUserUsername &&
    getTaskVOListData.value?.at(0)?.taskName !== '起草节点'
  );
});

const showProcessTask = computed(() => {
  return props.processInstanceId && myFirstTaskVO.value;
});

const handleProcessInstance = (commentType: '废弃' | '暂停' | '激活' | '撤回') => {
  taskOperate.commentType = commentType;
  handleTask();
};

watch(
  () => props.processInstanceId,
  value => {
    if (value) {
      reloadPageTable();
    } else {
      isFormDataEditable.value = true;
    }
  },
  {
    immediate: true
  }
);

watch(
  () => myFirstTaskVO.value,
  currentTaskVO => {
    if (currentTaskVO) {
      if (currentTaskVO.taskDelegationState === 'PENDING') {
        taskOperate.commentType = '回复';
      } else {
        taskOperate.commentType = '通过';
      }
    }
  },
  {
    immediate: true
  }
);

const processInstanceUploadDisabled = computed<boolean>(() => {
  if (myFirstTaskVO && myFirstTaskVO.value?.taskName === '起草节点') {
    return false;
  } else {
    return true;
  }
});
</script>
<template>
  <div class="container" ref="containerRef" style="width: 100%; height: 100%">
    <!-- 审批内容 -->
    <el-card shadow="hover">
      <template #header>
        <div class="title-button">
          <div class="title">审批内容</div>
          <div class="button">
            <span>
              <el-button
                type="primary"
                @click="handleStartProcessInstance"
                :loading="showHandleStartProcessInstanceButtonLoading"
                v-if="showHandleStartProcessInstanceButton"
              >
                提交
              </el-button>
            </span>

            <span>
              <el-radio-group v-model="isFormDataEditable" v-if="showCanChangeFormDataEditable">
                <el-radio-button label="查看" :value="false" />
                <el-radio-button label="编辑" :value="true" />
              </el-radio-group>
            </span>

            <span>
              <el-button type="primary" @click="router.push('/flowable/processInstance')">
                返回
              </el-button>
            </span>
            <span>
              <el-button type="primary" @click="handleClose">关闭</el-button>
            </span>
          </div>
        </div>
      </template>
      <template #default> <slot name="content" :isEditable="isFormDataEditable"></slot></template>
    </el-card>
    <!-- 审批内容 -->

    <!-- 流程附件 -->
    <el-card shadow="hover" v-if="processInstanceId">
      <template #header>流程附件</template>
      <template #default>
        <HqUploadMany :key-word="processInstanceId" :disabled="processInstanceUploadDisabled" />
      </template>
    </el-card>
    <!-- 流程附件 -->

    <!-- 当前流程 -->
    <el-card shadow="hover" v-if="props.processInstanceId">
      <template #header>
        <div class="title-button">
          <div class="title">流程信息</div>
          <div class="button">
            <el-button
              type="primary"
              @click="handleProcessInstance('撤回')"
              v-if="showWithDrawProcessInstanceButton"
            >
              撤回
            </el-button>
            <el-button
              type="danger"
              @click="handleProcessInstance('废弃')"
              v-if="showDeleteProcessInstanceButton"
            >
              废弃
            </el-button>
            <el-button
              type="warning"
              @click="handleProcessInstance('暂停')"
              v-if="showSuspendProcessInstanceButton"
            >
              暂停
            </el-button>
            <el-button
              type="success"
              @click="handleProcessInstance('激活')"
              v-if="showActiveProcessInstanceButton"
            >
              激活
            </el-button>
          </div>
        </div>
      </template>

      <template #default>
        <hq-form>
          <el-row :gutter="5">
            <HqCol>
              <el-form-item label="开始时间">
                <el-input :value="getProcessInstanceVOData?.processInstanceStartTime" readonly />
              </el-form-item>
            </HqCol>
            <HqCol>
              <el-form-item label="结束时间">
                <el-input :value="getProcessInstanceVOData?.processInstanceEndTime" readonly />
              </el-form-item>
            </HqCol>
            <HqCol>
              <el-form-item label="流程状态">
                <el-input :value="getProcessInstanceVOData?.processInstanceStatus" readonly />
              </el-form-item>
            </HqCol>
            <HqCol>
              <el-form-item label="起草人员">
                <el-input
                  :value="getProcessInstanceVOData?.processInstanceStartUserIdName"
                  readonly
                />
              </el-form-item>
            </HqCol>
          </el-row>
        </hq-form>
      </template>
    </el-card>
    <!-- 当前流程 -->

    <!-- 当前任务 -->
    <el-card shadow="hover" v-if="props.processInstanceId && getTaskVOListData?.length">
      <template #header>
        <div class="title-button">
          <div class="title">当前任务</div>
          <div class="button">
            <el-radio-group v-model="showMyTaskOnly">
              <el-radio-button :value="true">我的任务</el-radio-button>
              <el-radio-button :value="false">所有任务</el-radio-button>
            </el-radio-group>
          </div>
        </div>
      </template>
      <template #default>
        <hq-table-flowable
          title="用户任务列表"
          base-url=""
          :table-data="taskList"
          :loading="getTaskVOListLoading"
        >
          <template #columns>
            <hq-table-column label="taskId" prop="taskId" />
            <hq-table-column label="taskName" prop="taskName" />
            <hq-table-column label="taskAssignee" prop="taskAssigneeName" />
            <hq-table-column label="taskOwner" prop="taskOwnerName" />
            <hq-table-column label="taskDelegationState" prop="taskDelegationState" />
            <hq-table-column label="taskCreateTime" prop="taskCreateTime" />
          </template>
        </hq-table-flowable>
      </template>
    </el-card>
    <!-- 当前任务 -->

    <!-- 流程处理 -->
    <el-card shadow="hover" v-if="showProcessTask">
      <template #header>
        <div class="title-button">
          <div class="title">任务处理</div>
          <div class="button">
            <el-button type="primary" @click="handleTask">提交</el-button>
          </div>
        </div>
      </template>

      <template #default>
        <slot name="process">
          <hq-form>
            <el-form-item label="操作类型" prop="commentType">
              <el-radio-group v-model="taskOperate.commentType">
                <el-radio value="通过" label="通过" v-if="showCompleteTaskOption" />
                <el-radio value="驳回" label="驳回" v-if="showRejectTaskOption" />
                <el-radio value="转办" label="转办" v-if="showChangeAssigneeTaskOption" />
                <el-radio value="沟通" label="沟通" v-if="showDelegateTaskOption" />
                <el-radio value="回复" label="回复" v-if="showResolveTaskOption" />
              </el-radio-group>
            </el-form-item>

            <el-form-item
              label="办理人员"
              prop="userUsernameTo"
              v-if="taskOperate.commentType === '转办' || taskOperate.commentType === '沟通'"
            >
              <el-select v-model="taskOperate.userUsernameTo" filterable>
                <hq-user-options />
              </el-select>
            </el-form-item>

            <el-form-item label="处理意见" prop="commentMessage">
              <el-input
                v-model="taskOperate.commentMessage"
                type="textarea"
                :rows="5"
                resize="none"
              />
            </el-form-item>
          </hq-form>
        </slot>
      </template>
    </el-card>
    <!-- 流程处理 -->

    <!-- 审批历史 -->
    <el-card shadow="hover" v-if="props.processInstanceId">
      <template #header>审批历史</template>
      <template #default>
        <el-scrollbar>
          <hq-table
            :table-data="getCommentListByProcessInstanceIdData"
            :loading="getCommentListByProcessInstanceIdLoading"
            title="流程历史"
            base-url=""
          >
            <template #columns>
              <hq-table-column prop="taskName" label="taskName" />
              <hq-table-column prop="commentUserName" label="相关人员" />
              <el-table-column
                label="发起时间"
                align="center"
                :min-width="150"
                :formatter="row => dateTimeToDateTime(row.taskCreateTime as string)"
              />
              <el-table-column
                label="完成时间"
                align="center"
                :min-width="150"
                :formatter="row => dateTimeToDateTime(row.commentTime as string)"
              />
              <hq-table-column prop="commentType" label="意见类型" />
              <hq-table-column prop="commentMessage" label="意见详情" :min-width="400" />
            </template>
          </hq-table>
        </el-scrollbar>
      </template>
    </el-card>
    <!-- 审批历史 -->

    <!-- 流程审批人 -->
    <el-card shadow="hover">
      <template #header>流程审批人</template>
      <template #default>
        <slot name="table"> </slot>
      </template>
    </el-card>
    <!-- 流程审批人 -->

    <el-card shadow="hover" v-if="getProcessInstanceVOData?.processDefinitionDiagramResourceRaw">
      <template #header>流程定义图</template>
      <template #default>
        <HqBpmn
          :diagram-resource-raw="getProcessInstanceVOData.processDefinitionDiagramResourceRaw"
        />
      </template>
    </el-card>
  </div>
</template>
<style lang="scss" scoped>
.container {
  background-color: rgb(223, 230, 223);
  > * {
    margin-bottom: 5px;
  }

  > *:last-child {
    margin-bottom: 0;
  }
}

.title-button {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .button {
    display: flex;
    align-items: center;
    > span {
      margin-right: 10px;
    }

    > span:last-child {
      margin-right: 0;
    }
  }
}
</style>
